package org.jeecg.modules.gis.typeHandler.mysql;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ByteOrderValues;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * description: 网格工具 [描述信息]
 *
 * @author zhoumingyang [作者]
 * @version 1.0.0 [版本信息]
 * @date 2022/05/26 16:22:57 [时间，这里是年/月/日 时:分:秒的格式]
 */
public class MysqlGeoPolygonTypeHandler extends BaseTypeHandler<Polygon> {

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Polygon polygon, JdbcType jdbcType) throws SQLException {
        try {
            preparedStatement.setBytes(i, convertToBytes(polygon));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    public Polygon getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return convertToGeo(rs.getBytes(columnName));
    }


    @Override
    public Polygon getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
        return convertToGeo(resultSet.getBytes(columnIndex));
    }

    @Override
    public Polygon getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
        return convertToGeo(callableStatement.getBytes(columnIndex));
    }
    /**
     * bytes转Geo对象
     * @param bytes
     * @return
     */
    private Polygon convertToGeo(byte[] bytes) {
        if (bytes == null) {
            return null;
        }
        try {
            byte[] geomBytes = ByteBuffer.allocate(bytes.length - 4).order(ByteOrder.LITTLE_ENDIAN)
                    .put(bytes, 4, bytes.length - 4).array();
            Geometry geometry = new WKBReader().read(geomBytes);
            return (Polygon) geometry;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * geo转bytes
     * @param geometry
     * @return
     * @throws IOException
     */
    private byte[] convertToBytes(Geometry geometry) throws IOException {
        byte[] geometryBytes = new WKBWriter().write(geometry);
        byte[] wkb = new byte[geometryBytes.length + 4];
        //设置SRID为4326
        ByteOrderValues.putInt(4326, wkb, ByteOrderValues.LITTLE_ENDIAN);
        System.arraycopy(geometryBytes, 0, wkb, 4, geometryBytes.length);
        return wkb;
    }

}
